using System;
using System.Collections.Generic;
using System.Text;

using FlickrNet;

using Yorrick.FlickrMetadataSynchr.Data;

namespace Yorrick.FlickrMetadataSynchr.Flickr
{
    /// <summary>
    /// Static class that helps with Flickr metadata.
    /// </summary>
    public static class FlickrMetadataHelper
    {
        #region Public static methods
        /// <summary>
        /// Extracts relevant metadata to sync from a list of Flickr photo info objects.
        /// </summary>
        /// <param name="photoInfoList">A list with Flickr photoinfo objects.</param>
        /// <returns>The extracted metadata to sync as a list.</returns>
        public static IList<FlickrPictureMetadata> ExtractSyncMetadata(IList<PhotoInfo> photoInfoList)
        {
            List<FlickrPictureMetadata> pictureMetadataList = new List<FlickrPictureMetadata>(photoInfoList.Count);

            foreach (PhotoInfo photoInfo in photoInfoList)
            {
                pictureMetadataList.Add(ExtractSyncMetadata(photoInfo));
            }

            return pictureMetadataList.AsReadOnly();
        }

        /// <summary>
        /// Returns the set of "raw" tags as an array of strings. 
        /// </summary>
        /// <param name="flickrTags">A list of <see cref="PhotoInfoTag"/> items.</param>
        /// <returns>The set of "raw" tags.</returns>
        /// <remarks>"Raw" means the tags will have the original casing as entered by the user.</remarks>
        public static string[] GetTags(IList<PhotoInfoTag> flickrTags)
        {
            if (flickrTags == null)
            {
                return PictureMetadata.NoTags;
            }
            string[] tags = new string[flickrTags.Count];
            for (int counter = 0; counter < flickrTags.Count; counter++)
            {
                tags[counter] = flickrTags[counter].Raw;
            }

            return tags;
        }

        /// <summary>
        /// Extracts relevant metadata to sync from a Flickr <see cref="PhotoInfo"/> object.
        /// </summary>
        /// <param name="photoInfo">The Flickr <see cref="PhotoInfo"/> object.</param>
        /// <returns>The extracted metadata to sync.</returns>
        public static FlickrPictureMetadata ExtractSyncMetadata(PhotoInfo photoInfo)
        {
            FlickrPictureMetadata syncMetadata = new FlickrPictureMetadata(photoInfo.PhotoId);

            syncMetadata.DateTaken = photoInfo.DateTaken;
            syncMetadata.Title = FixQuotesAndAmpersands(photoInfo.Title);
            syncMetadata.Description = FixQuotesAndAmpersands(photoInfo.Description);
            syncMetadata.Author = photoInfo.OwnerRealName;
            syncMetadata.LastUpdated = DateTime.SpecifyKind(photoInfo.DateLastUpdated, DateTimeKind.Utc);
            if (photoInfo.Location != null)
            {
                syncMetadata.GpsLatitude = photoInfo.Location.Latitude;
                syncMetadata.GpsLongitude = photoInfo.Location.Longitude;
            }
            syncMetadata.Tags = GetTags(photoInfo.Tags);

            if (!String.IsNullOrEmpty(photoInfo.OriginalFormat))
            {
                syncMetadata.OriginalUrl = photoInfo.OriginalUrl;
            }

            syncMetadata.TrackChanges = true;

            return syncMetadata;
        }
        #endregion

        #region Private static methods
        /// <summary>
        /// Replaces &amp;quot; by " character.
        /// </summary>
        /// <param name="stringToFix">The string to fix.</param>
        /// <returns>The fixed string.</returns>
        private static string FixQuotesAndAmpersands(string stringToFix)
        {
            return stringToFix.Replace("&quot;", "\"").Replace("&amp;", "&");
        }
        #endregion
    }
}
